home *** CD-ROM | disk | FTP | other *** search
- #include "BaseConv.h"
-
- STXT VersTag[] = "$VER: " VSTR;
- STXT Compiled[] = "Compiled on " __DATE__ " at " __TIME__;
- STXT Copyright[] = "Copyright © 1994,95 Klaus Alexander Seistrup @ Magnetic Ink";
- STXT EMail[] = "E-mail: kas@mink.ping.dk";
-
- STXT Template[] = "BaseFrom/A,BaseTo/A,Numbers/A/M,-u=ToUpper/S,-l=ToLower/S";
- STXT ExtHelp[] = \
- "\n" \
- "33mUSAGE:0m 1mBaseConv0m <BaseFrom> <BaseTo> <Number1> [<Number2>...<NumberN>]\n" \
- "\n" \
- "\t<3mBaseFrom0m> and <3mBaseTo0m> must be numbers between 2 and 36\n" \
- "\t<3mNumber0m> must be lower than 2^32\n\n" \
- "BaseFrom/A,BaseTo/A,Numbers/A/M,-u=ToUpper/S,-l=ToLower/S";
-
- STXT OrigAuthor[] = \
- "Original author:\n" \
- "Xavier SIRVENT" \
- "71 Cours Saint Andr" \
- "F-38800 Le Pont de Claix";
-
-
- CFG GlobCFG;
-
-
-
- Prototype LONG FPrintF(BPTR,TEXT *,...);
- //
- LONG FPrintF(fh,ctl,...)
- BPTR fh;
- TEXT *ctl;
- {
- LONG cnt;
- va_list va;
-
- va_start(va,ctl);
- cnt = VFPrintf(fh,ctl,va);
- va_end(va);
-
- return (cnt);
- }
-
-
- Prototype VOID Usage(CFG *);
- //
- VOID
- Usage(cfg)
- CFG *cfg;
- {
- BPTR fh = cfg->fe ? cfg->fe : cfg->fo;
-
- if (fh)
- FPuts(fh,ExtHelp);
-
- Cleanup(cfg);
- }
-
-
- Prototype ULONG Rank(TEXT,ULONG);
- //
- ULONG
- Rank(charac,BaseFrom) // Returns the value of the "charac" given in base "BaseFrom"
- TEXT charac;
- ULONG BaseFrom;
- {
-
- LONG i = -1L;
- TEXT c = ToLower(charac);
-
- if (c >= '0' && c <= '9')
- i = c - '0';
- else if (c >= 'a' && c <= 'z')
- i = c - ('a' - 10);
-
- if ((i == -1) || (i >= BaseFrom))
- {
- CFG *cfg = &GlobCFG;
- BPTR fh = cfg->fe ? cfg->fe : cfg->fo;
-
- cfg->RC = RETURN_WARN;
- cfg->R2 = ERROR_BAD_NUMBER;
- cfg->ErrMsg = NULL;
-
- c = cfg->ToLower ? ToLower(c) : ToUpper(c);
-
- if (fh)
- FPrintF(fh,"33mERROR:0m 1m%lc0m is forbidden in base 1m%ld0m\n",c,BaseFrom);
-
- Cleanup(cfg);
- }
- return ((ULONG) i);
- }
-
-
- /*
- ** CSI =
- */
-
-
- Prototype ULONG ToBase10(TEXT *,ULONG);
- //
- ULONG
- ToBase10(num,BaseFrom) // Returns base 10 of "num" given in base "BaseFrom"
- TEXT *num;
- ULONG BaseFrom;
- {
- ULONG i;
- ULONG res1 = 0L;
- ULONG slen = strlen(num);
-
- for (i = 0l ; i < slen ; ++i)
- {
- ULONG res2 = UMul32(res1,BaseFrom) + Rank(num[i],BaseFrom);
-
- if (res2 <= res1)
- {
- CFG *cfg = &GlobCFG;
- BPTR fh = cfg->fe ? cfg->fe : cfg->fo;
-
- cfg->RC = RETURN_WARN;
- cfg->R2 = ERROR_BAD_NUMBER;
- cfg->ErrMsg = NULL;
-
- if (fh)
- FPrintF(fh,"33mERROR:0m 1m%s0m > 1m2^320m\n",num);
-
- Cleanup(cfg);
- }
- res1 = res2;
- }
- return (res1);
- }
-
-
-
- Prototype TEXT *FromBase10(ULONG,ULONG);
- //
- TEXT *
- FromBase10(num,BaseTo) // Display the number in BaseTo
- ULONG num,BaseTo;
- {
- STATIC TEXT RevBuf[128];
-
- TEXT tmp;
- TEXT *res = RevBuf;
-
- TEXT uchar = GlobCFG.ToLower ? 'a' : 'A';
-
- ULONG i = 0L;
- ULONG j = 0L;
- ULONG mod = 0L;
-
- /*
- ** The result is generated in reverse order
- */
- while ((num != 0L) && (i < 80L))
- {
- mod = UMod32(num,BaseTo);
-
- res[i++] = (mod <= 9) ? (mod + '0') : (mod - (10 - uchar));
- res[i] = 0;
-
- num = UDiv32(num,BaseTo);
- }
-
- /*
- ** making the result right order
- */
- while (j < (i >> 1))
- {
- ULONG k = i - j - 1;
-
- tmp = res[j];
-
- res[j] = res[k];
- res[k] = tmp;
-
- ++j;
- }
- return (res);
- }
-
-
-
- Prototype VOID Cleanup(CFG *);
- //
- VOID
- Cleanup(cfg)
- CFG *cfg;
- {
- BPTR fh = NULL;
-
- if (cfg->Args)
- FreeArgs(cfg->Args);
-
- if (cfg->DObj)
- FreeDosObject(DOS_RDARGS,cfg->DObj);
-
- if (cfg->fe)
- {
- fh = SelectOutput(cfg->fe);
-
- if (fh)
- Flush(fh);
- }
-
- if (cfg->R2 && cfg->RC != RETURN_WARN)
- PrintFault(cfg->R2,cfg->ErrMsg);
- else
- if (cfg->ErrMsg)
- PutStr(cfg->ErrMsg);
-
- if (cfg->fe)
- {
- fh = SelectOutput(fh);
-
- if (fh)
- Flush(fh);
-
- if (cfg->CloseFE)
- Close(cfg->fe);
- }
- SetIoErr(cfg->R2);
-
- _exit(cfg->RC);
- }
-
-
- Prototype TEXT *StrLower(TEXT *);
- //
- TEXT *
- StrLower(str)
- TEXT *str;
- {
- if (str)
- {
- TEXT *low = str;
-
- while (*str)
- {
- *str = ToLower(*str);
- ++str;
- }
- return (low);
- }
- return (NULL);
- }
-
-
- Prototype TEXT *StrUpper(TEXT *);
- //
- TEXT *
- StrUpper(str)
- TEXT *str;
- {
- if (str)
- {
- TEXT *upr = str;
-
- while (*str)
- {
- *str = ToUpper(*str);
- ++str;
- }
- return (upr);
- }
- return (NULL);
- }
-
-
-
- Prototype CFG *InitCFG(CFG *);
- //
- CFG *
- InitCFG(cfg)
- CFG *cfg;
- {
- cfg->fi = Input();
- cfg->fo = Output();
- cfg->fe = ((struct Process *)FindTask(NULL))->pr_CES;
-
- if (cfg->fe == NULL)
- {
- cfg->fe = Open("Console:",MODE_READWRITE);
-
- if (cfg->fe)
- cfg->CloseFE = TRUE;
- else
- cfg->fe = cfg->fo;
- }
- cfg->ErrMsg = VersTag+6;
-
- if ((cfg->DObj = (ARGS *)AllocDosObject(DOS_RDARGS,NULL)) == NULL)
- {
- cfg->RC = RETURN_ERROR;
- cfg->R2 = ERROR_NO_FREE_STORE;
- cfg->ErrMsg = "AllocDosObject()";
-
- Cleanup(cfg);
- }
- cfg->DObj->RDA_ExtHelp = ExtHelp;
-
- if ((cfg->Args = ReadArgs(Template,(LONG *)&(cfg->From),cfg->DObj)) == NULL)
- {
- cfg->RC = RETURN_ERROR;
- cfg->R2 = IoErr();
-
- Cleanup(cfg);
- }
-
- if (cfg->ToLower)
- cfg->ToLower = TRUE;
-
- if (cfg->ToUpper)
- cfg->ToUpper = TRUE;
-
- if (!(cfg->ToLower ^ cfg->ToUpper))
- {
- cfg->ToLower = TRUE;
- cfg->ToUpper = FALSE;
- }
-
- cfg->From = cfg->ToLower ? StrLower(cfg->From) : StrUpper(cfg->From);
- cfg->To = cfg->ToLower ? StrLower(cfg->To) : StrUpper(cfg->To);
- {
- ULONG i = 0L;
- TEXT **num = cfg->Number;
-
- while (num[i])
- {
- num[i] = cfg->ToLower ? StrLower(num[i]) : StrUpper(num[i]);
- ++i;
- }
- }
- return (cfg);
- }
-
-
-
-
- Prototype LONG _main(VOID);
- //
- LONG
- _main(VOID)
- {
- if (Cli())
- {
- ULONG i = 0L;
- CFG *cfg = InitCFG(&GlobCFG);
-
- StrToLong(cfg->From,&(cfg->BaseFrom));
- StrToLong(cfg->To,&(cfg->BaseTo));
-
- if ((cfg->BaseFrom > 36) || (cfg->BaseTo > 36) || (cfg->BaseFrom < 2) || (cfg->BaseTo < 2))
- {
- BPTR fh = cfg->fe ? cfg->fe : cfg->fo;
-
- cfg->RC = RETURN_WARN;
- cfg->R2 = ERROR_BAD_NUMBER;
- cfg->ErrMsg = NULL;
-
- if (fh)
- FPuts(fh,"33mERROR:0m <3mBaseFrom0m> and <3mBaseTo0m> must be in [2..36]\n");
-
- Cleanup(cfg);
- }
-
- while (cfg->Number[i])
- {
- FPrintf(cfg->fo,"%s = %s\n",cfg->Number[i],FromBase10(ToBase10(cfg->Number[i],cfg->BaseFrom),cfg->BaseTo));
- ++i;
-
- if (CheckSignal(SIGBREAKF_CTRL_C))
- {
- cfg->RC = 1L;
- cfg->R2 = 304L;
-
- cfg->ErrMsg = NULL;
-
- Cleanup(cfg);
- }
- }
- cfg->RC = 0L;
- cfg->R2 = 0L;
- cfg->ErrMsg = 0L;
-
- Cleanup(cfg);
- }
- return (-1L);
- }
-
-
- /*
- ** EOF
- */
-